Added GtkScrollablePolicy property to scrollable interface
authorTristan Van Berkom <tristan.van.berkom@gmail.com>
Tue, 26 Oct 2010 00:59:02 +0000 (09:59 +0900)
committerTristan Van Berkom <tristan.van.berkom@gmail.com>
Tue, 26 Oct 2010 01:15:56 +0000 (10:15 +0900)
This patch adds the GtkScrollablePolicy type property to GtkScrollable
and implements it in all subclasses. GtkScrolledWindow observes this
property to make a good guess about when to show/hide scrollbars for
height-for-width content.

Most scrollable children do not do height-for-width *yet* but
most certainly will (toolpalette, treeview, iconview, textview
widgets all TODO), for scrollable widgets that do have a minimum
and natural size, it's important for them to observe the state
of this property in order to properly drive the scroll adjustments
according to the desired GtkScrollablePolicy. This patch makes
GtkViewport do this.

Patch also adds tests/testscrolledwindow.c to display the effects
of this property.

12 files changed:
gtk/gtkenums.h
gtk/gtkiconview.c
gtk/gtklayout.c
gtk/gtkscrollable.c
gtk/gtkscrollable.h
gtk/gtkscrolledwindow.c
gtk/gtktextview.c
gtk/gtktoolpalette.c
gtk/gtktreeprivate.h
gtk/gtktreeview.c
gtk/gtkviewport.c
tests/Makefile.am

index 5e5271bf76fadf949aebf5251914fd72292b55a9..6075c266f08858830be6acff78de1d853d389b12 100644 (file)
@@ -541,6 +541,21 @@ typedef enum
   GTK_SIZE_REQUEST_WIDTH_FOR_HEIGHT
 } GtkSizeRequestMode;
 
+/**
+ * GtkScrollablePolicy:
+ * @GTK_SCROLL_MINIMUM: Scrollable adjustments are based on the minimum size
+ * @GTK_SCROLL_NATURAL: Scrollable adjustments are based on the natural size
+ *
+ * Defines the policy to be used in a scrollable widget when updating
+ * the scrolled window adjustments in a given orientation.
+ */
+typedef enum
+{
+  GTK_SCROLL_MINIMUM = 0,
+  GTK_SCROLL_NATURAL
+} GtkScrollablePolicy;
+
+
 G_END_DECLS
 
 
index d844de8683611af24e6daf7c32f53fd03564086e..de282d04ac8d603b57c0b8c9da2c1d2883d96c83 100644 (file)
@@ -205,6 +205,11 @@ struct _GtkIconViewPrivate
   guint shift_pressed : 1;
 
   guint draw_focus : 1;
+
+  /* GtkScrollablePolicy needs to be checked when
+   * driving the scrollable adjustment values */
+  guint hscroll_policy : 1;
+  guint vscroll_policy : 1;
 };
 
 /* Signals */
@@ -243,7 +248,9 @@ enum
 
   /* For scrollable interface */
   PROP_HADJUSTMENT,
-  PROP_VADJUSTMENT
+  PROP_VADJUSTMENT,
+  PROP_HSCROLL_POLICY,
+  PROP_VSCROLL_POLICY
 };
 
 /* GObject vfuncs */
@@ -794,8 +801,10 @@ gtk_icon_view_class_init (GtkIconViewClass *klass)
                                                     GTK_PARAM_READWRITE));
 
   /* Scrollable interface properties */
-  g_object_class_override_property (gobject_class, PROP_HADJUSTMENT, "hadjustment");
-  g_object_class_override_property (gobject_class, PROP_VADJUSTMENT, "vadjustment");
+  g_object_class_override_property (gobject_class, PROP_HADJUSTMENT,    "hadjustment");
+  g_object_class_override_property (gobject_class, PROP_VADJUSTMENT,    "vadjustment");
+  g_object_class_override_property (gobject_class, PROP_HSCROLL_POLICY, "hscroll-policy");
+  g_object_class_override_property (gobject_class, PROP_VSCROLL_POLICY, "vscroll-policy");
 
   /* Style properties */
   gtk_widget_class_install_style_property (widget_class,
@@ -1205,6 +1214,14 @@ gtk_icon_view_set_property (GObject      *object,
     case PROP_VADJUSTMENT:
       gtk_icon_view_set_vadjustment (icon_view, g_value_get_object (value));
       break;
+    case PROP_HSCROLL_POLICY:
+      icon_view->priv->hscroll_policy = g_value_get_enum (value);
+      gtk_widget_queue_resize (GTK_WIDGET (icon_view));
+      break;
+    case PROP_VSCROLL_POLICY:
+      icon_view->priv->vscroll_policy = g_value_get_enum (value);
+      gtk_widget_queue_resize (GTK_WIDGET (icon_view));
+      break;
 
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -1277,6 +1294,12 @@ gtk_icon_view_get_property (GObject      *object,
     case PROP_VADJUSTMENT:
       g_value_set_object (value, icon_view->priv->vadjustment);
       break;
+    case PROP_HSCROLL_POLICY:
+      g_value_set_enum (value, icon_view->priv->hscroll_policy);
+      break;
+    case PROP_VSCROLL_POLICY:
+      g_value_set_enum (value, icon_view->priv->vscroll_policy);
+      break;
 
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
index ec06056eb9045db7e92bd2eecd51c7b665930811..266d6c8f94ad0a86f764fe1fd7c516509c9e087a 100644 (file)
@@ -53,6 +53,11 @@ struct _GtkLayoutPrivate
   GtkAdjustment *hadjustment;
   GtkAdjustment *vadjustment;
 
+  /* GtkScrollablePolicy needs to be checked when
+   * driving the scrollable adjustment values */
+  guint hscroll_policy : 1;
+  guint vscroll_policy : 1;
+
   /* Properties */
 
   GdkVisibilityState visibility;
@@ -75,7 +80,9 @@ struct _GtkLayoutChild {
 enum {
    PROP_0,
    PROP_HADJUSTMENT,
-   PROP_VADJUSTMENT,
+   PROP_VADJUSTMENT, 
+   PROP_HSCROLL_POLICY,
+   PROP_VSCROLL_POLICY,
    PROP_WIDTH,
    PROP_HEIGHT
 };
@@ -618,8 +625,10 @@ gtk_layout_class_init (GtkLayoutClass *class)
                                                                 GTK_PARAM_READWRITE));
   
   /* Scrollable interface */
-  g_object_class_override_property (gobject_class, PROP_HADJUSTMENT, "hadjustment");
-  g_object_class_override_property (gobject_class, PROP_VADJUSTMENT, "vadjustment");
+  g_object_class_override_property (gobject_class, PROP_HADJUSTMENT,    "hadjustment");
+  g_object_class_override_property (gobject_class, PROP_VADJUSTMENT,    "vadjustment");
+  g_object_class_override_property (gobject_class, PROP_HSCROLL_POLICY, "hscroll-policy");
+  g_object_class_override_property (gobject_class, PROP_VSCROLL_POLICY, "vscroll-policy");
 
   g_object_class_install_property (gobject_class,
                                   PROP_WIDTH,
@@ -671,6 +680,12 @@ gtk_layout_get_property (GObject     *object,
     case PROP_VADJUSTMENT:
       g_value_set_object (value, priv->vadjustment);
       break;
+    case PROP_HSCROLL_POLICY:
+      g_value_set_enum (value, priv->hscroll_policy);
+      break;
+    case PROP_VSCROLL_POLICY:
+      g_value_set_enum (value, priv->vscroll_policy);
+      break;
     case PROP_WIDTH:
       g_value_set_uint (value, priv->width);
       break;
@@ -702,6 +717,14 @@ gtk_layout_set_property (GObject      *object,
       gtk_layout_set_vadjustment (layout, 
                                  (GtkAdjustment*) g_value_get_object (value));
       break;
+    case PROP_HSCROLL_POLICY:
+      priv->hscroll_policy = g_value_get_enum (value);
+      gtk_widget_queue_resize (GTK_WIDGET (layout));
+      break;
+    case PROP_VSCROLL_POLICY:
+      priv->vscroll_policy = g_value_get_enum (value);
+      gtk_widget_queue_resize (GTK_WIDGET (layout));
+      break;
     case PROP_WIDTH:
       gtk_layout_set_size (layout, g_value_get_uint (value),
                           priv->height);
index 3e19c79ca6d7b5d7484cf6faaee3c54310e8aaff..ca0d8a4ea4d94d40ed504560981fca2cf22d8d38 100644 (file)
@@ -63,6 +63,7 @@
 #include "config.h"
 
 #include "gtkscrollable.h"
+#include "gtktypeutils.h"
 #include "gtkprivate.h"
 #include "gtkintl.h"
 
@@ -106,6 +107,38 @@ gtk_scrollable_default_init (GtkScrollableInterface *iface)
                                GTK_TYPE_ADJUSTMENT,
                                GTK_PARAM_READWRITE | G_PARAM_CONSTRUCT);
   g_object_interface_install_property (iface, pspec);
+
+  /**
+   * GtkScrollable:hscroll-policy:
+   *
+   * Determines whether horizontal scrolling should commence once the scrollable 
+   * widget is allocated less than it's minimum width or less than it's natural width.
+   *
+   * Since: 3.0
+   */
+  pspec = g_param_spec_enum ("hscroll-policy",
+                            P_("Horizontal Scrollable Policy"),
+                            P_("How the size of the content should be determined"),
+                            GTK_TYPE_SCROLLABLE_POLICY,
+                            GTK_SCROLL_MINIMUM,
+                            GTK_PARAM_READWRITE);
+  g_object_interface_install_property (iface, pspec);
+
+  /**
+   * GtkScrollable:vscroll-policy:
+   *
+   * Determines whether vertical scrolling should commence once the scrollable 
+   * widget is allocated less than it's minimum height or less than it's natural height.
+   *
+   * Since: 3.0
+   */
+  pspec = g_param_spec_enum ("vscroll-policy",
+                            P_("Vertical Scrollable Policy"),
+                            P_("How the size of the content should be determined"),
+                            GTK_TYPE_SCROLLABLE_POLICY,
+                            GTK_SCROLL_MINIMUM,
+                            GTK_PARAM_READWRITE);
+  g_object_interface_install_property (iface, pspec);
 }
 
 /**
@@ -203,3 +236,88 @@ gtk_scrollable_set_vadjustment (GtkScrollable *scrollable,
 
   g_object_set (scrollable, "vadjustment", vadjustment, NULL);
 }
+
+
+/**
+ * gtk_scrollable_get_hscroll_policy:
+ * @scrollable: a #GtkScrollable
+ *
+ * Gets the horizontal #GtkScrollablePolicy.
+ *
+ * Return value: The horizontal #GtkScrollablePolicy.
+ *
+ * Since: 3.0
+ **/
+GtkScrollablePolicy
+gtk_scrollable_get_hscroll_policy (GtkScrollable *scrollable)
+{
+  GtkScrollablePolicy policy;
+
+  g_return_val_if_fail (GTK_IS_SCROLLABLE (scrollable), GTK_SCROLL_MINIMUM);
+
+  g_object_get (scrollable, "hscroll-policy", &policy, NULL);
+
+  return policy;
+}
+
+/**
+ * gtk_scrollable_set_hscroll_policy:
+ * @scrollable: a #GtkScrollable
+ * @policy: the horizontal #GtkScrollablePolicy
+ *
+ * Sets the #GtkScrollablePolicy to determine whether 
+ * horizontal scrolling should commence below minimum or
+ * below natural width.
+ *
+ * Since: 3.0
+ **/
+void
+gtk_scrollable_set_hscroll_policy (GtkScrollable       *scrollable,
+                                  GtkScrollablePolicy  policy)
+{
+  g_return_if_fail (GTK_IS_SCROLLABLE (scrollable));
+
+  g_object_set (scrollable, "hscroll-policy", policy, NULL);
+}
+
+/**
+ * gtk_scrollable_get_vscroll_policy:
+ * @scrollable: a #GtkScrollable
+ *
+ * Gets the vertical #GtkScrollablePolicy.
+ *
+ * Return value: The vertical #GtkScrollablePolicy.
+ *
+ * Since: 3.0
+ **/
+GtkScrollablePolicy
+gtk_scrollable_get_vscroll_policy (GtkScrollable *scrollable)
+{
+  GtkScrollablePolicy policy;
+
+  g_return_val_if_fail (GTK_IS_SCROLLABLE (scrollable), GTK_SCROLL_MINIMUM);
+
+  g_object_get (scrollable, "vscroll-policy", &policy, NULL);
+
+  return policy;
+}
+
+/**
+ * gtk_scrollable_set_vscroll_policy:
+ * @scrollable: a #GtkScrollable
+ * @policy: the vertical #GtkScrollablePolicy
+ *
+ * Sets the #GtkScrollablePolicy to determine whether 
+ * vertical scrolling should commence below minimum or
+ * below natural height.
+ *
+ * Since: 3.0
+ **/
+void
+gtk_scrollable_set_vscroll_policy (GtkScrollable       *scrollable,
+                                  GtkScrollablePolicy  policy)
+{
+  g_return_if_fail (GTK_IS_SCROLLABLE (scrollable));
+
+  g_object_set (scrollable, "vscroll-policy", policy, NULL);
+}
index fdb1c1127349bc0d0c4f55f53b2819746c4ec4bb..8f15a43d7278bd0c4016c4cfaa0135bac026293e 100644 (file)
@@ -25,6 +25,7 @@
 #define __GTK_SCROLLABLE_H__
 
 #include <gtk/gtkadjustment.h>
+#include <gtk/gtkenums.h>
 
 G_BEGIN_DECLS
 
@@ -42,13 +43,19 @@ struct _GtkScrollableInterface
 };
 
 /* Public API */
-GType          gtk_scrollable_get_type               (void) G_GNUC_CONST;
-GtkAdjustment *gtk_scrollable_get_hadjustment        (GtkScrollable *scrollable);
-void           gtk_scrollable_set_hadjustment        (GtkScrollable *scrollable,
-                                                      GtkAdjustment *hadjustment);
-GtkAdjustment *gtk_scrollable_get_vadjustment        (GtkScrollable *scrollable);
-void           gtk_scrollable_set_vadjustment        (GtkScrollable *scrollable,
-                                                      GtkAdjustment *vadjustment);
+GType                gtk_scrollable_get_type               (void) G_GNUC_CONST;
+GtkAdjustment       *gtk_scrollable_get_hadjustment        (GtkScrollable       *scrollable);
+void                 gtk_scrollable_set_hadjustment        (GtkScrollable       *scrollable,
+                                                           GtkAdjustment       *hadjustment);
+GtkAdjustment       *gtk_scrollable_get_vadjustment        (GtkScrollable       *scrollable);
+void                 gtk_scrollable_set_vadjustment        (GtkScrollable       *scrollable,
+                                                           GtkAdjustment       *vadjustment);
+GtkScrollablePolicy  gtk_scrollable_get_hscroll_policy     (GtkScrollable       *scrollable);
+void                 gtk_scrollable_set_hscroll_policy     (GtkScrollable       *scrollable,
+                                                           GtkScrollablePolicy  policy);
+GtkScrollablePolicy  gtk_scrollable_get_vscroll_policy     (GtkScrollable       *scrollable);
+void                 gtk_scrollable_set_vscroll_policy     (GtkScrollable       *scrollable,
+                                                           GtkScrollablePolicy  policy);
 
 G_END_DECLS
 
index 02fe2a5f50309f6b0ae3d2d848b6edd9a731aa52..489d6872d760f55cc9288a4dc16a396737e30c4e 100644 (file)
@@ -1460,8 +1460,6 @@ gtk_scrolled_window_size_allocate (GtkWidget     *widget,
   gint sb_width;
   gint sb_height;
  
-
-
   g_return_if_fail (GTK_IS_SCROLLED_WINDOW (widget));
   g_return_if_fail (allocation != NULL);
 
@@ -1491,8 +1489,8 @@ gtk_scrolled_window_size_allocate (GtkWidget     *widget,
   child = gtk_bin_get_child (bin);
   if (child && gtk_widget_get_visible (child))
     {
-      gint child_min_width;
-      gint child_min_height;
+      gint child_scroll_width;
+      gint child_scroll_height;
       gboolean previous_hvis;
       gboolean previous_vvis;
       guint count = 0;
@@ -1509,41 +1507,50 @@ gtk_scrolled_window_size_allocate (GtkWidget     *widget,
          /* Determine scrollbar visibility first via hfw apis */
          if (gtk_widget_get_request_mode (child) == GTK_SIZE_REQUEST_HEIGHT_FOR_WIDTH)
            {
-             gtk_widget_get_preferred_width (child, &child_min_width, NULL);
-             
+             if (gtk_scrollable_get_hscroll_policy (GTK_SCROLLABLE (child)) == GTK_SCROLL_MINIMUM)
+               gtk_widget_get_preferred_width (child, &child_scroll_width, NULL);
+             else
+               gtk_widget_get_preferred_width (child, NULL, &child_scroll_width);
+
              if (priv->vscrollbar_policy == GTK_POLICY_AUTOMATIC)
                {
                  /* First try without a vertical scrollbar if the content will fit the height
                   * given the extra width of the scrollbar */
-                 gtk_widget_get_preferred_height_for_width (child, allocation->width, 
-                                                            &child_min_height, NULL);
-                 
+                 if (gtk_scrollable_get_vscroll_policy (GTK_SCROLLABLE (child)) == GTK_SCROLL_MINIMUM)
+                   gtk_widget_get_preferred_height_for_width (child, 
+                                                              MAX (allocation->width, child_scroll_width), 
+                                                              &child_scroll_height, NULL);
+                 else
+                   gtk_widget_get_preferred_height_for_width (child,
+                                                              MAX (allocation->width, child_scroll_width), 
+                                                              NULL, &child_scroll_height);
+
                  if (priv->hscrollbar_policy == GTK_POLICY_AUTOMATIC)
                    {
                      /* Does the content height fit the allocation height ? */
-                     priv->vscrollbar_visible = child_min_height > allocation->height;
+                     priv->vscrollbar_visible = child_scroll_height > allocation->height;
                      
                      /* Does the content width fit the allocation with minus a possible scrollbar ? */
                      priv->hscrollbar_visible = 
-                       child_min_width > allocation->width - 
+                       child_scroll_width > allocation->width - 
                        (priv->vscrollbar_visible ? sb_width + sb_spacing : 0);
                      
                      /* Now that we've guessed the hscrollbar, does the content height fit
                       * the possible new allocation height ? */
                      priv->vscrollbar_visible = 
-                       child_min_height > allocation->height - 
+                       child_scroll_height > allocation->height - 
                        (priv->hscrollbar_visible ? sb_height + sb_spacing : 0);
                      
                      /* Now that we've guessed the vscrollbar, does the content width fit
                       * the possible new allocation width ? */
                      priv->hscrollbar_visible = 
-                       child_min_width > allocation->width - 
+                       child_scroll_width > allocation->width - 
                        (priv->vscrollbar_visible ? sb_width + sb_spacing : 0);
                    }
                  else /* priv->hscrollbar_policy != GTK_POLICY_AUTOMATIC */
                    {
                      priv->hscrollbar_visible = priv->hscrollbar_policy != GTK_POLICY_NEVER;
-                     priv->vscrollbar_visible = child_min_height > allocation->height - 
+                     priv->vscrollbar_visible = child_scroll_height > allocation->height - 
                        (priv->hscrollbar_visible ? sb_height + sb_spacing : 0);
                    }
                }
@@ -1553,7 +1560,7 @@ gtk_scrolled_window_size_allocate (GtkWidget     *widget,
                  
                  if (priv->hscrollbar_policy == GTK_POLICY_AUTOMATIC)
                    priv->hscrollbar_visible = 
-                     child_min_width > allocation->width - 
+                     child_scroll_width > allocation->width - 
                      (priv->vscrollbar_visible ? 0 : sb_width + sb_spacing);
                  else
                    priv->hscrollbar_visible = priv->hscrollbar_policy != GTK_POLICY_NEVER;
@@ -1561,41 +1568,50 @@ gtk_scrolled_window_size_allocate (GtkWidget     *widget,
            } 
          else /* GTK_SIZE_REQUEST_WIDTH_FOR_HEIGHT */
            {
-             gtk_widget_get_preferred_height (child, &child_min_height, NULL);
-             
+             if (gtk_scrollable_get_vscroll_policy (GTK_SCROLLABLE (child)) == GTK_SCROLL_MINIMUM)
+               gtk_widget_get_preferred_height (child, &child_scroll_height, NULL);
+             else
+               gtk_widget_get_preferred_height (child, NULL, &child_scroll_height);
+
              if (priv->hscrollbar_policy == GTK_POLICY_AUTOMATIC)
                {
                  /* First try without a horizontal scrollbar if the content will fit the width
                   * given the extra height of the scrollbar */
-                 gtk_widget_get_preferred_width_for_height (child, allocation->height, 
-                                                            &child_min_width, NULL);
+                 if (gtk_scrollable_get_hscroll_policy (GTK_SCROLLABLE (child)) == GTK_SCROLL_MINIMUM)
+                   gtk_widget_get_preferred_width_for_height (child, 
+                                                              MAX (allocation->height, child_scroll_height), 
+                                                              &child_scroll_width, NULL);
+                 else
+                   gtk_widget_get_preferred_width_for_height (child, 
+                                                              MAX (allocation->height, child_scroll_height), 
+                                                              NULL, &child_scroll_width);
                  
                  if (priv->vscrollbar_policy == GTK_POLICY_AUTOMATIC)
                    {
                      /* Does the content width fit the allocation width ? */
-                     priv->hscrollbar_visible = child_min_width > allocation->width;
+                     priv->hscrollbar_visible = child_scroll_width > allocation->width;
                      
                      /* Does the content height fit the allocation with minus a possible scrollbar ? */
                      priv->vscrollbar_visible = 
-                       child_min_height > allocation->height - 
+                       child_scroll_height > allocation->height - 
                        (priv->hscrollbar_visible ? sb_height + sb_spacing : 0);
                      
                      /* Now that we've guessed the vscrollbar, does the content width fit
                       * the possible new allocation width ? */
                      priv->hscrollbar_visible = 
-                       child_min_width > allocation->width - 
+                       child_scroll_width > allocation->width - 
                        (priv->vscrollbar_visible ? sb_width + sb_spacing : 0);
                      
                      /* Now that we've guessed the hscrollbar, does the content height fit
                       * the possible new allocation height ? */
                      priv->vscrollbar_visible = 
-                       child_min_height > allocation->height - 
+                       child_scroll_height > allocation->height - 
                        (priv->hscrollbar_visible ? sb_height + sb_spacing : 0);
                    }
                  else /* priv->vscrollbar_policy != GTK_POLICY_AUTOMATIC */
                    {
                      priv->vscrollbar_visible = priv->vscrollbar_policy != GTK_POLICY_NEVER;
-                     priv->hscrollbar_visible = child_min_width > allocation->width - 
+                     priv->hscrollbar_visible = child_scroll_width > allocation->width - 
                        (priv->vscrollbar_visible ? sb_width + sb_spacing : 0);
                    }
                }
@@ -1605,7 +1621,7 @@ gtk_scrolled_window_size_allocate (GtkWidget     *widget,
                  
                  if (priv->vscrollbar_policy == GTK_POLICY_AUTOMATIC)
                    priv->vscrollbar_visible = 
-                     child_min_height > allocation->height - 
+                     child_scroll_height > allocation->height - 
                      (priv->hscrollbar_visible ? 0 : sb_height + sb_spacing);
                  else
                    priv->vscrollbar_visible = priv->vscrollbar_policy != GTK_POLICY_NEVER;
index f0eca6575fc9d68dc18a88b0a46ad385cd6eda88..ae12071c8925c0f7e6dc3f2625dfd537e3ed0dcc 100644 (file)
@@ -210,6 +210,11 @@ struct _GtkTextViewPrivate
   guint mouse_cursor_obscured : 1;
 
   guint scroll_after_paste : 1;
+
+  /* GtkScrollablePolicy needs to be checked when
+   * driving the scrollable adjustment values */
+  guint hscroll_policy : 1;
+  guint vscroll_policy : 1;
 };
 
 struct _GtkTextPendingScroll
@@ -260,7 +265,9 @@ enum
   PROP_ACCEPTS_TAB,
   PROP_IM_MODULE,
   PROP_HADJUSTMENT,
-  PROP_VADJUSTMENT
+  PROP_VADJUSTMENT,
+  PROP_HSCROLL_POLICY,
+  PROP_VSCROLL_POLICY
 };
 
 static void gtk_text_view_finalize             (GObject          *object);
@@ -771,8 +778,10 @@ gtk_text_view_class_init (GtkTextViewClass *klass)
                                                          GTK_PARAM_READWRITE));
 
    /* GtkScrollable interface */
-   g_object_class_override_property (gobject_class, PROP_HADJUSTMENT, "hadjustment");
-   g_object_class_override_property (gobject_class, PROP_VADJUSTMENT, "vadjustment");
+   g_object_class_override_property (gobject_class, PROP_HADJUSTMENT,    "hadjustment");
+   g_object_class_override_property (gobject_class, PROP_VADJUSTMENT,    "vadjustment");
+   g_object_class_override_property (gobject_class, PROP_HSCROLL_POLICY, "hscroll-policy");
+   g_object_class_override_property (gobject_class, PROP_VSCROLL_POLICY, "vscroll-policy");
 
   /*
    * Style properties
@@ -3092,6 +3101,16 @@ gtk_text_view_set_property (GObject         *object,
       gtk_text_view_set_vadjustment (text_view, g_value_get_object (value));
       break;
 
+    case PROP_HSCROLL_POLICY:
+      priv->hscroll_policy = g_value_get_enum (value);
+      gtk_widget_queue_resize (GTK_WIDGET (text_view));
+      break;
+
+    case PROP_VSCROLL_POLICY:
+      priv->vscroll_policy = g_value_get_enum (value);
+      gtk_widget_queue_resize (GTK_WIDGET (text_view));
+      break;
+
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -3180,6 +3199,14 @@ gtk_text_view_get_property (GObject         *object,
       g_value_set_object (value, priv->vadjustment);
       break;
 
+    case PROP_HSCROLL_POLICY:
+      g_value_set_enum (value, priv->hscroll_policy);
+      break;
+
+    case PROP_VSCROLL_POLICY:
+      g_value_set_enum (value, priv->vscroll_policy);
+      break;
+
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
index 6d9c5c13f6845cb17b54f9dac104c870fe809577..bc60c3d2108c66da47dfae95d264557376f5a902 100644 (file)
@@ -122,7 +122,9 @@ enum
   PROP_ORIENTATION,
   PROP_TOOLBAR_STYLE,
   PROP_HADJUSTMENT,
-  PROP_VADJUSTMENT
+  PROP_VADJUSTMENT,
+  PROP_HSCROLL_POLICY,
+  PROP_VSCROLL_POLICY
 };
 
 enum
@@ -159,10 +161,15 @@ struct _GtkToolPalettePrivate
 
   GtkSizeGroup         *text_size_group;
 
-  GtkSettings       *settings;
-  gulong             settings_connection;
+  GtkSettings          *settings;
+  gulong                settings_connection;
 
   guint                 drag_source : 2;
+
+  /* GtkScrollablePolicy needs to be checked when
+   * driving the scrollable adjustment values */
+  guint hscroll_policy : 1;
+  guint vscroll_policy : 1;
 };
 
 struct _GtkToolPaletteDragData
@@ -276,6 +283,16 @@ gtk_tool_palette_set_property (GObject      *object,
         gtk_tool_palette_set_vadjustment (palette, g_value_get_object (value));
         break;
 
+      case PROP_HSCROLL_POLICY:
+       palette->priv->hscroll_policy = g_value_get_enum (value);
+       gtk_widget_queue_resize (GTK_WIDGET (palette));
+       break;
+
+      case PROP_VSCROLL_POLICY:
+       palette->priv->vscroll_policy = g_value_get_enum (value);
+       gtk_widget_queue_resize (GTK_WIDGET (palette));
+       break;
+
       default:
         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
         break;
@@ -316,6 +333,14 @@ gtk_tool_palette_get_property (GObject    *object,
         g_value_set_object (value, palette->priv->vadjustment);
         break;
 
+      case PROP_HSCROLL_POLICY:
+       g_value_set_enum (value, palette->priv->hscroll_policy);
+       break;
+
+      case PROP_VSCROLL_POLICY:
+       g_value_set_enum (value, palette->priv->vscroll_policy);
+       break;
+
       default:
         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
         break;
@@ -952,10 +977,12 @@ gtk_tool_palette_class_init (GtkToolPaletteClass *cls)
    */
   wclass->screen_changed      = gtk_tool_palette_screen_changed;
 
-  g_object_class_override_property (oclass, PROP_ORIENTATION, "orientation");
+  g_object_class_override_property (oclass, PROP_ORIENTATION,    "orientation");
 
-  g_object_class_override_property (oclass, PROP_HADJUSTMENT, "hadjustment");
-  g_object_class_override_property (oclass, PROP_VADJUSTMENT, "vadjustment");
+  g_object_class_override_property (oclass, PROP_HADJUSTMENT,    "hadjustment");
+  g_object_class_override_property (oclass, PROP_VADJUSTMENT,    "vadjustment");
+  g_object_class_override_property (oclass, PROP_HSCROLL_POLICY, "hscroll-policy");
+  g_object_class_override_property (oclass, PROP_VSCROLL_POLICY, "vscroll-policy");
 
   /**
    * GtkToolPalette:icon-size:
index 1ac35a8e4afedd4abe1be8443017708209e07c2f..2304f69ab7523e32ba7e9836d114a2f52afd30a9 100644 (file)
@@ -302,6 +302,11 @@ struct _GtkTreeViewPrivate
 
   /* Whether our key press handler is to avoid sending an unhandled binding to the search entry */
   guint search_entry_avoid_unhandled_binding : 1;
+
+  /* GtkScrollablePolicy needs to be checked when
+   * driving the scrollable adjustment values */
+  guint hscroll_policy : 1;
+  guint vscroll_policy : 1;
 };
 
 #ifdef __GNUC__
index e849bb4141f945fe5a3945bb07cecaa442dbc930..de2bb259631ee55295565de85713094c57c1b9bc 100644 (file)
@@ -131,6 +131,8 @@ enum {
   PROP_MODEL,
   PROP_HADJUSTMENT,
   PROP_VADJUSTMENT,
+  PROP_HSCROLL_POLICY,
+  PROP_VSCROLL_POLICY,
   PROP_HEADERS_VISIBLE,
   PROP_HEADERS_CLICKABLE,
   PROP_EXPANDER_COLUMN,
@@ -568,8 +570,10 @@ gtk_tree_view_class_init (GtkTreeViewClass *class)
                                                        GTK_TYPE_TREE_MODEL,
                                                        GTK_PARAM_READWRITE));
 
-  g_object_class_override_property (o_class, PROP_HADJUSTMENT, "hadjustment");
-  g_object_class_override_property (o_class, PROP_VADJUSTMENT, "vadjustment");
+  g_object_class_override_property (o_class, PROP_HADJUSTMENT,    "hadjustment");
+  g_object_class_override_property (o_class, PROP_VADJUSTMENT,    "vadjustment");
+  g_object_class_override_property (o_class, PROP_HSCROLL_POLICY, "hscroll-policy");
+  g_object_class_override_property (o_class, PROP_VSCROLL_POLICY, "vscroll-policy");
 
   g_object_class_install_property (o_class,
                                    PROP_HEADERS_VISIBLE,
@@ -1366,6 +1370,14 @@ gtk_tree_view_set_property (GObject         *object,
     case PROP_VADJUSTMENT:
       gtk_tree_view_set_vadjustment (tree_view, g_value_get_object (value));
       break;
+    case PROP_HSCROLL_POLICY:
+      tree_view->priv->hscroll_policy = g_value_get_enum (value);
+      gtk_widget_queue_resize (GTK_WIDGET (tree_view));
+      break;
+    case PROP_VSCROLL_POLICY:
+      tree_view->priv->vscroll_policy = g_value_get_enum (value);
+      gtk_widget_queue_resize (GTK_WIDGET (tree_view));
+      break;
     case PROP_HEADERS_VISIBLE:
       gtk_tree_view_set_headers_visible (tree_view, g_value_get_boolean (value));
       break;
@@ -1441,6 +1453,12 @@ gtk_tree_view_get_property (GObject    *object,
     case PROP_VADJUSTMENT:
       g_value_set_object (value, tree_view->priv->vadjustment);
       break;
+    case PROP_HSCROLL_POLICY:
+      g_value_set_enum (value, tree_view->priv->hscroll_policy);
+      break;
+    case PROP_VSCROLL_POLICY:
+      g_value_set_enum (value, tree_view->priv->vscroll_policy);
+      break;
     case PROP_HEADERS_VISIBLE:
       g_value_set_boolean (value, gtk_tree_view_get_headers_visible (tree_view));
       break;
index 4389646325a56846cb5d9bced914b0c78663b75b..573910dcdc7354b424f303843eda4f05721c1d1c 100644 (file)
@@ -66,14 +66,19 @@ struct _GtkViewportPrivate
 
   GdkWindow      *bin_window;
   GdkWindow      *view_window;
+
+  /* GtkScrollablePolicy needs to be checked when
+   * driving the scrollable adjustment values */
+  guint hscroll_policy : 1;
+  guint vscroll_policy : 1;
 };
 
 enum {
   PROP_0,
   PROP_HADJUSTMENT,
   PROP_VADJUSTMENT,
-  PROP_MIN_DISPLAY_WIDTH,
-  PROP_MIN_DISPLAY_HEIGHT,
+  PROP_HSCROLL_POLICY,
+  PROP_VSCROLL_POLICY,
   PROP_SHADOW_TYPE
 };
 
@@ -139,8 +144,10 @@ gtk_viewport_class_init (GtkViewportClass *class)
   container_class->add = gtk_viewport_add;
 
   /* GtkScrollable implementation */
-  g_object_class_override_property (gobject_class, PROP_HADJUSTMENT, "hadjustment");
-  g_object_class_override_property (gobject_class, PROP_VADJUSTMENT, "vadjustment");
+  g_object_class_override_property (gobject_class, PROP_HADJUSTMENT,    "hadjustment");
+  g_object_class_override_property (gobject_class, PROP_VADJUSTMENT,    "vadjustment");
+  g_object_class_override_property (gobject_class, PROP_HSCROLL_POLICY, "hscroll-policy");
+  g_object_class_override_property (gobject_class, PROP_VSCROLL_POLICY, "vscroll-policy");
 
   g_object_class_install_property (gobject_class,
                                    PROP_SHADOW_TYPE,
@@ -172,6 +179,14 @@ gtk_viewport_set_property (GObject         *object,
     case PROP_VADJUSTMENT:
       gtk_viewport_set_vadjustment (viewport, g_value_get_object (value));
       break;
+    case PROP_HSCROLL_POLICY:
+      viewport->priv->hscroll_policy = g_value_get_enum (value);
+      gtk_widget_queue_resize (GTK_WIDGET (viewport));
+      break;
+    case PROP_VSCROLL_POLICY:
+      viewport->priv->vscroll_policy = g_value_get_enum (value);
+      gtk_widget_queue_resize (GTK_WIDGET (viewport));
+      break;
     case PROP_SHADOW_TYPE:
       gtk_viewport_set_shadow_type (viewport, g_value_get_enum (value));
       break;
@@ -198,6 +213,12 @@ gtk_viewport_get_property (GObject         *object,
     case PROP_VADJUSTMENT:
       g_value_set_object (value, priv->vadjustment);
       break;
+    case PROP_HSCROLL_POLICY:
+      g_value_set_enum (value, priv->hscroll_policy);
+      break;
+    case PROP_VSCROLL_POLICY:
+      g_value_set_enum (value, priv->vscroll_policy);
+      break;
     case PROP_SHADOW_TYPE:
       g_value_set_enum (value, priv->shadow_type);
       break;
@@ -414,13 +435,23 @@ viewport_set_hadjustment_values (GtkViewport *viewport,
   child = gtk_bin_get_child (bin);
   if (child && gtk_widget_get_visible (child))
     {
-      gint minimum_width;
+      gint minimum_width, natural_width;
+      gint scroll_height;
+      
+      if (viewport->priv->vscroll_policy == GTK_SCROLL_MINIMUM)
+       gtk_widget_get_preferred_height (child, &scroll_height, NULL);
+      else
+       gtk_widget_get_preferred_height (child, NULL, &scroll_height);
 
       gtk_widget_get_preferred_width_for_height (child,
-                                                 view_allocation.height,
+                                                 MAX (view_allocation.height, scroll_height),
                                                  &minimum_width,
-                                                 NULL);
-      hadjustment->upper = MAX (minimum_width, view_allocation.width);
+                                                 &natural_width);
+
+      if (viewport->priv->hscroll_policy == GTK_SCROLL_MINIMUM)
+       hadjustment->upper = MAX (minimum_width, view_allocation.width);
+      else
+       hadjustment->upper = MAX (natural_width, view_allocation.width);
     }
   else
     hadjustment->upper = view_allocation.width;
@@ -456,14 +487,23 @@ viewport_set_vadjustment_values (GtkViewport *viewport,
   child = gtk_bin_get_child (bin);
   if (child && gtk_widget_get_visible (child))
     {
-      gint minimum_height;
+      gint minimum_height, natural_height;
+      gint scroll_width;
+
+      if (viewport->priv->hscroll_policy == GTK_SCROLL_MINIMUM)
+       gtk_widget_get_preferred_width (child, &scroll_width, NULL);
+      else
+       gtk_widget_get_preferred_width (child, NULL, &scroll_width);
 
       gtk_widget_get_preferred_height_for_width (child,
-                                                 view_allocation.width,
+                                                 MAX (view_allocation.width, scroll_width),
                                                  &minimum_height,
-                                                 NULL);
+                                                 &natural_height);
 
-      vadjustment->upper = MAX (minimum_height, view_allocation.height);
+      if (viewport->priv->vscroll_policy == GTK_SCROLL_MINIMUM)
+       vadjustment->upper = MAX (minimum_height, view_allocation.height);
+      else
+       vadjustment->upper = MAX (natural_height, view_allocation.height);
     }
   else
     vadjustment->upper = view_allocation.height;
index 6132dc874374e1f2621a8324f5d1bda12108b3c9..9daf69a9680769916fc1aaa38fa2fbe3c965e8ff 100644 (file)
@@ -93,7 +93,8 @@ noinst_PROGRAMS =  $(TEST_PROGS)      \
        testtooltips                    \
        testexpand                      \
        testexpander                    \
-       testvolumebutton
+       testvolumebutton                \
+       testscrolledwindow
 
 if USE_X11
 noinst_PROGRAMS += testerrors
@@ -177,6 +178,7 @@ testactions_DEPENDENCIES = $(TEST_DEPS)
 testgrouping_DEPENDENCIES = $(TEST_DEPS)
 testtooltips_DEPENDENCIES = $(TEST_DEPS)
 testvolumebutton_DEPENDENCIES = $(TEST_DEPS)
+testscrolledwindow_DEPENDENCIES = $(TEST_DEPS)
 testwindows_DEPENDENCIES = $(TEST_DEPS)
 testexpand_DEPENDENCIES = $(TEST_DEPS)
 testexpander_DEPENDENCIES = $(TEST_DEPS)
@@ -249,6 +251,7 @@ testactions_LDADD = $(LDADDS)
 testgrouping_LDADD = $(LDADDS)
 testtooltips_LDADD = $(LDADDS)
 testvolumebutton_LDADD = $(LDADDS)
+testscrolledwindow_LDADD = $(LDADDS)
 testwindows_LDADD = $(LDADDS)
 testexpand_LDADD = $(LDADDS)
 testexpander_LDADD = $(LDADDS)
@@ -355,6 +358,9 @@ testrecentchoosermenu_SOURCES =     \
 testvolumebutton_SOURCES =     \
        testvolumebutton.c
 
+testscrolledwindow_SOURCES =   \
+       testscrolledwindow.c
+
 testoffscreen_SOURCES =        \
        gtkoffscreenbox.c       \
        gtkoffscreenbox.h       \